package com.hanxiaozhang.delayqueue.no1;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.DelayQueue;

/**
 * 〈一句话功能简述〉<br>
 * 〈订单延迟队列服务〉
 *
 * @author hanxinghua
 * @create 2022/9/11
 * @since 1.0.0
 */
@Slf4j
@Component
public class OrderDelayServiceImpl implements DelayService<OrderEntry> {

    @Autowired
    @Qualifier(value = "asyncExecutor")
    private ThreadPoolTaskExecutor executor;

    private final static DelayQueue<ItemDelayed<OrderEntry>> DELAY_QUEUE = new DelayQueue<>();

    /**
     * 初始化时加载数据库中需处理超时的订单
     * / @PostConstruct 在容器启动后，只进行一次初始化
     */
    @PostConstruct
    public void init() {
        // todo 扫描数据库中未支付,未过期的的订单的接口
        List<OrderEntry> orderList = new ArrayList<>();
        for (OrderEntry order : orderList) {
            ItemDelayed<OrderEntry> orderDelayed = new ItemDelayed<>(order.getId(), order.getCreateDate().getTime());
            this.addToDelayQueue(orderDelayed);
        }
        log.info("系统启动:扫描数据库中未支付的订单,总共扫描了[{}]个订单,已经添加到延迟队列!", orderList.size());
        /*启动一个线程，去取延迟订单*/
        executor.execute(() -> {
            log.info("启动延迟队列处理线程，线程名称:[{}]", Thread.currentThread().getName());
            ItemDelayed<OrderEntry> orderDelayed;
            while (true) {
                try {
                    orderDelayed = DELAY_QUEUE.take();
                    Long orderId = orderDelayed.getDataId();
                    // 调用业务逻辑  todo
                } catch (Exception e) {
                    log.error("延迟队列异常，异常信息:[{}]", e);
                }
            }
        });
    }


    /**
     * 加入延迟消息队列
     *
     * @param orderDelayed
     * @return
     */
    @Override
    public boolean addToDelayQueue(ItemDelayed<OrderEntry> orderDelayed) {
        return DELAY_QUEUE.add(orderDelayed);
    }


    /**
     * 加入延迟消息队列
     *
     * @param order
     * @return
     */
    @Override
    public boolean addToDelayQueue(OrderEntry order) {
        ItemDelayed<OrderEntry> orderDelayed = new ItemDelayed<>(order.getId(), order.getCreateDate().getTime());
        return DELAY_QUEUE.add(orderDelayed);
    }


    /**
     * 从延迟队列中移除 主动取消就主动从队列中取出
     *
     * @param order
     */
    @Override
    public void removeToDelayQueue(OrderEntry order) {
        if (order == null) {
            return;
        }
        for (Iterator<ItemDelayed<OrderEntry>> iterator = DELAY_QUEUE.iterator(); iterator.hasNext(); ) {
            ItemDelayed<OrderEntry> queue = iterator.next();
            if (queue.getDataId().equals(order.getId())) {
                DELAY_QUEUE.remove(queue);
            }
        }
    }

}
